home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / sozobon2.zoo / tools / globs.c < prev    next >
C/C++ Source or Header  |  1990-12-13  |  6KB  |  373 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    Program to remove local symbols from Alcyon .o's or archives
  12.  *
  13.  * 02OCT88
  14.  *    dal: fixed temp file rename problem using _splitpath/_makepath
  15.  *         and made several error handling changes.  Also added the
  16.  *         '-s' switch for "silent" operation.
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <ar.h>
  21.  
  22. #define MAXGL    2048
  23.  
  24. struct hdr {
  25.     int magic;
  26.     long tsize, dsize, bsize;
  27.     long syms;
  28.     long f1,f2;
  29.     int f3;
  30. } h;
  31.  
  32. struct sym {
  33.     char name[8];
  34.     char flags;
  35.     long value;
  36. };
  37.  
  38. FILE        *outfd;
  39. int        nnew;
  40. int        s_flag = FALSE;        /* operate silently */
  41. char        *filename = NULL;    /* current filename */
  42. int        many = FALSE;        /* more than one source file */
  43.  
  44. usage()
  45. {
  46.     fprintf(stderr, "usage: globs [-s] file...\n");
  47.     fprintf(stderr, "  remove non-essential symbols\n");
  48.     exit(1);
  49. }
  50.  
  51. main(argc, argv)
  52. int argc;
  53. char *argv[];
  54. {
  55.     while(--argc && (**++argv == '-'))
  56.         doopt(*argv);
  57.  
  58.     if (argc < 1)
  59.         usage();
  60.  
  61.     many = (argc > 1);
  62.  
  63.     while (argc--)
  64.         doname(*argv++);
  65.  
  66.     putchar('\n');
  67. }
  68.  
  69. doopt(s)
  70. register char *s;
  71. {
  72.     while (*++s)
  73.         switch (*s) {
  74. #ifdef G_FLAG
  75.         case 'g':
  76.             g_flag = TRUE;
  77. #endif
  78.         case 's':
  79.             s_flag = TRUE;
  80.         default:
  81.             fprintf(stderr, "globs: illegal option '%c'\n", *s);
  82.             usage();
  83.         }
  84.     }
  85.  
  86. doname(s)
  87. char *s;
  88. {
  89.     FILE *fd, *fopen();
  90.     int i, n, nlost;
  91.     char pbuf[128], drive[4], path[128];
  92.  
  93.     filename = s;
  94.     fd = fopen(s, "rb");
  95.     if (fd == NULL) {
  96.         fprintf(stderr, "globs: can't open '%s'\n", s);
  97.         return;
  98.     }
  99.  
  100.     _splitpath(s, drive, path, NULL, NULL);
  101.     _makepath(pbuf, drive, path, "_globs", "tmp");
  102.     outfd = fopen(pbuf, "wb");
  103.     if (outfd == NULL) {
  104.         fprintf(stderr, "globs: can't open tmp file\n");
  105.         fclose(fd);
  106.         exit(EXIT_FAILURE);
  107.     }
  108.  
  109.     if (many && !s_flag)
  110.         printf("processing %s\n", s);
  111.  
  112.     if (i = dohdr(fd)) {
  113.         if (i == -1)
  114.             doarch(fd);
  115.         else {
  116.             startsyms();
  117.             for (n=0; n<i; n++)
  118.                 dosym(fd, n);
  119.             nlost = i - nnew;
  120.             if (!s_flag)
  121.                 printf("removed %d symbols\n", nlost);
  122.             if (nlost == 0) {
  123.                 fclose(fd);
  124.                 return;
  125.             }
  126.             rewind(fd);
  127.             redo(fd);
  128.             dorel(fd);
  129.         }
  130.     } else
  131.         exit(1);
  132.         
  133.     fclose(fd);
  134.     fclose(outfd);
  135.  
  136.     if (unlink(s) || rename(pbuf, s)) {
  137.         fprintf(stderr, "globs: unlink/rename error on '%s'\n", s);
  138.         exit(EXIT_FAILURE);
  139.     }
  140. }
  141.  
  142. dohdr(fd)
  143. FILE *fd;
  144. {
  145.     int i;
  146.     long len;
  147.  
  148.     fread(&h, 2, 1, fd);
  149.     if (h.magic == ARMAG1)
  150.         return -1;
  151.     i = fread((char *)&h + 2, sizeof(h) - 2, 1, fd);
  152.     if (i != 1 || h.magic != 0x601a) {
  153.         printf("globs: bad header on '%s'\n", filename);
  154.         return 0;
  155.     }
  156.     len = h.tsize + h.dsize;
  157.     fseek(fd, len, 1);
  158.     return(h.syms / sizeof(struct sym));
  159. }
  160.  
  161. struct newsym {
  162.     int oldnum;
  163.     struct sym sy;
  164. } ns[MAXGL];
  165.  
  166. findx(x)
  167. {
  168.     register i;
  169.  
  170.     x >>= 3;
  171.     for (i=0; i<nnew; i++)
  172.         if (ns[i].oldnum == x) {
  173.             x = i;
  174.             goto okay;
  175.         }
  176.     printf("globs: can't find sym %d in '%s'\n", x, filename);
  177.     exit(EXIT_FAILURE);
  178. okay:
  179.     x = (x<<3) + 4;
  180.     return x;
  181. }
  182.  
  183. redo(fd)
  184. FILE *fd;
  185. {
  186.     register i;
  187.     long oldsyms;
  188.  
  189.     fread(&h, sizeof(h), 1, fd);
  190.     oldsyms = h.syms;
  191.     h.syms = (long)nnew * sizeof(struct sym);
  192.     fwrite(&h, sizeof(h), 1, outfd);
  193.  
  194.     lcopy(fd, h.tsize+h.dsize);
  195.     fseek(fd, oldsyms, 1);
  196.     for (i=0; i<nnew; i++)
  197.         fwrite(&ns[i].sy, sizeof(struct sym), 1, outfd);    
  198. }
  199.  
  200. #define BSIZE 1024
  201.  
  202. lcopy(fd, len)
  203. FILE *fd;
  204. long len;
  205. {
  206.     int n;
  207.     char buf[BSIZE];
  208.  
  209.     while (len) {
  210.         n = len > BSIZE ? BSIZE : len;
  211.         fread(buf, n, 1, fd);
  212.         fwrite(buf, n, 1, outfd);
  213.         len -= n;
  214.     }
  215. }
  216.  
  217. startsyms()
  218. {
  219.     nnew = 0;
  220. }
  221.  
  222. dosym(fd, oldn)
  223. FILE *fd;
  224. {
  225.     struct sym s;
  226.     int i;
  227.  
  228.     i = fread(&s, sizeof(s), 1, fd);
  229.     if (i != 1)
  230.         return;
  231.     if (not_glob(s.flags))
  232.         return;
  233.     ns[nnew].sy = s;
  234.     ns[nnew].oldnum = oldn;
  235.     nnew++;
  236. }
  237.  
  238. fill8(s)
  239. char *s;
  240. {
  241.     int i;
  242.  
  243.     for (i=0; i<8; i++)
  244.         if (s[i] == 0)
  245.             putchar(' ');
  246. }
  247.  
  248. char *fname[] = {
  249.     "?0?", "bss", "text", "?3?", "data",
  250.     "?5?", "?6?", "?7?"
  251. };
  252.  
  253. not_glob(x)
  254. {
  255.     x &= 0xff;
  256.     if (x & 0x20)
  257.         return 0;
  258.     x &= ~0x20;
  259.     if (x == 0x88)
  260.         return 0;
  261.     return 1;
  262. }
  263.  
  264. #ifdef NEVER
  265. sflags(x)
  266. {
  267.     x &= 0xff;
  268.     if (x & 0x20)
  269.         printf("global ");
  270.     x &= ~0x20;
  271.     if (x == 0x88)
  272.         printf("external abs");
  273.     else if (x == 0xc0)
  274.         printf("equ abs");
  275.     else if (x == 0xd0)
  276.         printf("equ reg abs");
  277.     else {
  278.         x &= 7;
  279.         printf(fname[x]);
  280.     }
  281. }
  282. #endif
  283.  
  284. doarch(fd)
  285. FILE *fd;
  286. {
  287.     struct ar_hdr a;
  288.     int i, n, nlost, x;
  289.     long astart, ostart, ftell();
  290.  
  291.     i = ARMAG1;
  292.     fwrite(&i, sizeof(int), 1, outfd);
  293. more:
  294.     i = fread(&a, sizeof(a), 1, fd);
  295.     if (i != 1)
  296.         goto out;
  297.  
  298.     if (!s_flag)
  299.         printf("\n(%.18s):\n", a.ar_name);
  300.     ostart = ftell(fd);
  301.     astart = ostart + a.ar_size;
  302.  
  303.     i = dohdr(fd);
  304.     if (i <= 0)
  305.         return;
  306.  
  307.     startsyms();
  308.     for (n=0; n<i; n++)
  309.         dosym(fd, n);
  310.  
  311.     nlost = i-nnew;
  312.     if (!s_flag)
  313.         printf("removed %d symbols\n", nlost);
  314.  
  315.     a.ar_size = sizeof(h) + 2*(h.tsize+h.dsize) +
  316.             nnew*sizeof(struct sym);
  317.  
  318.     fwrite(&a, sizeof(a), 1, outfd);
  319.  
  320.     fseek(fd, ostart, 0);
  321.     redo(fd);
  322.     dorel(fd);
  323.  
  324.     fseek(fd, astart, 0);
  325.     goto more;
  326.  
  327. out:
  328.     x = ftell(outfd);
  329.     x &= 0xff;
  330.     if (x)
  331.         zeroes(0x100 - x);
  332. }
  333.  
  334. char zbuf[0x100];
  335.  
  336. zeroes(n)
  337. {
  338.     if (!s_flag)
  339.         printf("fill %d\n", n);
  340.     fwrite(zbuf, n, 1, outfd);
  341. }
  342.  
  343. dorel(fd)
  344. FILE *fd;
  345. {
  346.     long num, i;
  347.     long here, ftell();
  348.     int x;
  349.  
  350.     here = ftell(fd);
  351.     num = (h.tsize + h.dsize)/((long) sizeof(int));
  352.     if (!s_flag)
  353.         printf("at %lx, %ld words\n", here, num);
  354.     for (i=0; i<num; i++) {
  355.         fread(&x, sizeof(int), 1, fd);
  356.         fwrite(&x, sizeof(int), 1, outfd);
  357.         switch (x) {
  358.         case 7:
  359.         case 0:
  360.             break;
  361.         case 5:
  362.             fread(&x, sizeof(int), 1, fd);
  363.             i++;
  364.             if ((x & 7) == 4)
  365.                 x = findx(x);
  366.             fwrite(&x, sizeof(int), 1, outfd);
  367.             break;
  368.         default:
  369.             printf("?%x? ", x);
  370.         }
  371.     }
  372. }
  373.